<template>
  <div class="form-designer">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <div class="toolbar-left">
        <el-button type="primary" @click="handleSave" :icon="DocumentAdd">
          保存表单
        </el-button>
        <el-button @click="handlePreview" :icon="View">
          预览
        </el-button>
        <el-button @click="handleClear" :icon="Delete">
          清空
        </el-button>
        <el-button @click="handleImport" :icon="Upload">
          导入JSON
        </el-button>
        <el-button @click="handleExport" :icon="Download">
          导出JSON
        </el-button>
      </div>
      <div class="toolbar-right">
        <span class="form-name">{{ formConfig.name || '未命名表单' }}</span>
      </div>
    </div>

    <div class="designer-container">
      <!-- 左侧组件库 -->
      <div class="component-panel">
        <div class="panel-header">
          <h3>组件库</h3>
        </div>
        <div class="component-list">
          <div class="component-group" v-for="group in componentGroups" :key="group.name">
            <div class="group-title">{{ group.name }}</div>
            <div class="group-items">
              <div 
                v-for="component in group.components" 
                :key="component.type"
                class="component-item"
                draggable="true"
                @dragstart="handleDragStart(component)"
              >
                <el-icon><component :is="component.icon" /></el-icon>
                <span>{{ component.label }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 中间设计区域 -->
      <div class="design-panel">
        <div class="panel-header">
          <h3>表单设计</h3>
          <div class="design-actions">
            <el-button size="small" @click="handleFormConfig" :icon="Setting">
              表单配置
            </el-button>
          </div>
        </div>
        <div 
          class="design-area"
          @drop="handleDrop"
          @dragover="handleDragOver"
          @dragenter="handleDragEnter"
        >
          <div v-if="formItems.length === 0" class="empty-design">
            <el-icon class="empty-icon"><Plus /></el-icon>
            <p>拖拽左侧组件到此处开始设计表单</p>
          </div>
          <div v-else class="form-items">
            <div 
              v-for="(item, index) in formItems" 
              :key="item.id"
              class="form-item-wrapper"
              :class="{ active: selectedItem?.id === item.id }"
              @click="selectItem(item)"
            >
              <div class="form-item-content">
                <component 
                  :is="getComponentByType(item.type)"
                  v-bind="item.props"
                  :model-value="item.defaultValue"
                  disabled
                />
              </div>
              <div class="form-item-actions">
                <el-button size="small" type="primary" @click.stop="moveUp(index)" :disabled="index === 0">
                  <el-icon><ArrowUp /></el-icon>
                </el-button>
                <el-button size="small" type="primary" @click.stop="moveDown(index)" :disabled="index === formItems.length - 1">
                  <el-icon><ArrowDown /></el-icon>
                </el-button>
                <el-button size="small" type="danger" @click.stop="removeItem(index)">
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧属性配置 -->
      <div class="property-panel">
        <div class="panel-header">
          <h3>属性配置</h3>
        </div>
        <div class="property-content">
          <div v-if="!selectedItem" class="no-selection">
            <p>请选择一个组件进行配置</p>
          </div>
          <div v-else class="property-form">
            <el-form :model="selectedItem" label-width="80px" size="small">
              <!-- 基础属性 -->
              <div class="property-group">
                <div class="group-title">基础属性</div>
                <el-form-item label="字段名">
                  <el-input v-model="selectedItem.field" placeholder="请输入字段名" />
                </el-form-item>
                <el-form-item label="标签">
                  <el-input v-model="selectedItem.label" placeholder="请输入标签" />
                </el-form-item>
                <el-form-item label="占位符">
                  <el-input v-model="selectedItem.props.placeholder" placeholder="请输入占位符" />
                </el-form-item>
                <el-form-item label="默认值">
                  <el-input v-model="selectedItem.defaultValue" placeholder="请输入默认值" />
                </el-form-item>
                <el-form-item label="必填">
                  <el-switch v-model="selectedItem.required" />
                </el-form-item>
                <el-form-item label="禁用">
                  <el-switch v-model="selectedItem.props.disabled" />
                </el-form-item>
              </div>

              <!-- 特殊属性 -->
              <div class="property-group" v-if="selectedItem.type === 'select' || selectedItem.type === 'radio' || selectedItem.type === 'checkbox'">
                <div class="group-title">选项配置</div>
                <div class="options-config">
                  <div v-for="(option, index) in selectedItem.options" :key="index" class="option-item">
                    <el-input v-model="option.label" placeholder="标签" size="small" />
                    <el-input v-model="option.value" placeholder="值" size="small" />
                    <el-button size="small" type="danger" @click="removeOption(index)">
                      <el-icon><Delete /></el-icon>
                    </el-button>
                  </div>
                  <el-button size="small" @click="addOption">添加选项</el-button>
                </div>
              </div>

              <!-- 验证规则 -->
              <div class="property-group">
                <div class="group-title">验证规则</div>
                <el-form-item label="最小长度" v-if="selectedItem.type === 'input' || selectedItem.type === 'textarea'">
                  <el-input-number v-model="selectedItem.validation.minLength" :min="0" />
                </el-form-item>
                <el-form-item label="最大长度" v-if="selectedItem.type === 'input' || selectedItem.type === 'textarea'">
                  <el-input-number v-model="selectedItem.validation.maxLength" :min="0" />
                </el-form-item>
                <el-form-item label="正则表达式">
                  <el-input v-model="selectedItem.validation.pattern" placeholder="请输入正则表达式" />
                </el-form-item>
                <el-form-item label="错误提示">
                  <el-input v-model="selectedItem.validation.message" placeholder="请输入错误提示" />
                </el-form-item>
              </div>
            </el-form>
          </div>
        </div>
      </div>
    </div>

    <!-- 表单配置对话框 -->
    <el-dialog v-model="formConfigVisible" title="表单配置" width="500px">
      <el-form :model="formConfig" label-width="100px">
        <el-form-item label="表单名称">
          <el-input v-model="formConfig.name" placeholder="请输入表单名称" />
        </el-form-item>
        <el-form-item label="表单描述">
          <el-input v-model="formConfig.description" type="textarea" placeholder="请输入表单描述" />
        </el-form-item>
        <el-form-item label="标签宽度">
          <el-input v-model="formConfig.labelWidth" placeholder="如：100px" />
        </el-form-item>
        <el-form-item label="表单大小">
          <el-select v-model="formConfig.size">
            <el-option label="大" value="large" />
            <el-option label="默认" value="default" />
            <el-option label="小" value="small" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="formConfigVisible = false">取消</el-button>
        <el-button type="primary" @click="saveFormConfig">确定</el-button>
      </template>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog v-model="previewVisible" title="表单预览" width="800px">
      <div class="preview-content">
        <el-form 
          :model="previewData"
          :label-width="formConfig.labelWidth || '100px'"
          :size="formConfig.size || 'default'"
        >
          <el-form-item 
            v-for="item in formItems" 
            :key="item.id"
            :label="item.label"
            :required="item.required"
          >
            <component 
              :is="getComponentByType(item.type)"
              v-model="previewData[item.field]"
              v-bind="item.props"
            >
              <template v-if="item.type === 'select' || item.type === 'radio' || item.type === 'checkbox'">
                <el-option 
                  v-for="option in item.options" 
                  :key="option.value"
                  :label="option.label"
                  :value="option.value"
                />
              </template>
            </component>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <el-button @click="previewVisible = false">关闭</el-button>
        <el-button type="primary" @click="handlePreviewSubmit">提交测试</el-button>
      </template>
    </el-dialog>

    <!-- JSON导入对话框 -->
    <el-dialog v-model="importVisible" title="导入JSON配置" width="600px">
      <el-input 
        v-model="importJson"
        type="textarea"
        :rows="10"
        placeholder="请粘贴JSON配置"
      />
      <template #footer>
        <el-button @click="importVisible = false">取消</el-button>
        <el-button type="primary" @click="handleImportConfirm">导入</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  DocumentAdd, View, Delete, Upload, Download, Setting, Plus,
  ArrowUp, ArrowDown, Edit, Calendar, Clock, User, Phone,
  Message, Lock, Star, Flag, Tag, Link
} from '@element-plus/icons-vue'

// 组件库配置
const componentGroups = ref([
  {
    name: '基础组件',
    components: [
      { type: 'input', label: '单行文本', icon: 'Edit' },
      { type: 'textarea', label: '多行文本', icon: 'Document' },
      { type: 'number', label: '数字输入', icon: 'Calculator' },
      { type: 'password', label: '密码输入', icon: 'Lock' }
    ]
  },
  {
    name: '选择组件',
    components: [
      { type: 'select', label: '下拉选择', icon: 'ArrowDown' },
      { type: 'radio', label: '单选框', icon: 'CircleCheck' },
      { type: 'checkbox', label: '多选框', icon: 'Check' },
      { type: 'switch', label: '开关', icon: 'Switch' }
    ]
  },
  {
    name: '日期时间',
    components: [
      { type: 'date', label: '日期选择', icon: 'Calendar' },
      { type: 'datetime', label: '日期时间', icon: 'Clock' },
      { type: 'time', label: '时间选择', icon: 'Timer' }
    ]
  },
  {
    name: '其他组件',
    components: [
      { type: 'rate', label: '评分', icon: 'Star' },
      { type: 'slider', label: '滑块', icon: 'Minus' },
      { type: 'upload', label: '文件上传', icon: 'Upload' }
    ]
  }
])

// 表单配置
const formConfig = reactive({
  name: '',
  description: '',
  labelWidth: '100px',
  size: 'default'
})

// 表单项列表
const formItems = ref([])

// 选中的组件
const selectedItem = ref(null)

// 对话框状态
const formConfigVisible = ref(false)
const previewVisible = ref(false)
const importVisible = ref(false)

// 预览数据
const previewData = ref({})

// 导入JSON
const importJson = ref('')

// 拖拽开始
const handleDragStart = (component) => {
  // 存储拖拽的组件信息
  window.dragComponent = component
}

// 拖拽进入
const handleDragEnter = (e) => {
  e.preventDefault()
}

// 拖拽悬停
const handleDragOver = (e) => {
  e.preventDefault()
}

// 拖拽放置
const handleDrop = (e) => {
  e.preventDefault()
  const component = window.dragComponent
  if (component) {
    addFormItem(component)
  }
}

// 添加表单项
const addFormItem = (component) => {
  const id = Date.now().toString()
  const item = {
    id,
    type: component.type,
    label: component.label,
    field: `field_${id}`,
    required: false,
    defaultValue: '',
    props: {
      placeholder: `请输入${component.label}`,
      disabled: false
    },
    validation: {
      minLength: null,
      maxLength: null,
      pattern: '',
      message: ''
    },
    options: component.type === 'select' || component.type === 'radio' || component.type === 'checkbox' ? [
      { label: '选项1', value: 'option1' },
      { label: '选项2', value: 'option2' }
    ] : []
  }
  
  formItems.value.push(item)
  selectedItem.value = item
}

// 选择组件
const selectItem = (item) => {
  selectedItem.value = item
}

// 移除组件
const removeItem = (index) => {
  formItems.value.splice(index, 1)
  if (selectedItem.value && selectedItem.value.id === formItems.value[index]?.id) {
    selectedItem.value = null
  }
}

// 上移组件
const moveUp = (index) => {
  if (index > 0) {
    const item = formItems.value.splice(index, 1)[0]
    formItems.value.splice(index - 1, 0, item)
  }
}

// 下移组件
const moveDown = (index) => {
  if (index < formItems.value.length - 1) {
    const item = formItems.value.splice(index, 1)[0]
    formItems.value.splice(index + 1, 0, item)
  }
}

// 添加选项
const addOption = () => {
  if (selectedItem.value) {
    selectedItem.value.options.push({
      label: `选项${selectedItem.value.options.length + 1}`,
      value: `option${selectedItem.value.options.length + 1}`
    })
  }
}

// 移除选项
const removeOption = (index) => {
  if (selectedItem.value) {
    selectedItem.value.options.splice(index, 1)
  }
}

// 根据类型获取组件
const getComponentByType = (type) => {
  const componentMap = {
    input: 'el-input',
    textarea: 'el-input',
    number: 'el-input-number',
    password: 'el-input',
    select: 'el-select',
    radio: 'el-radio-group',
    checkbox: 'el-checkbox-group',
    switch: 'el-switch',
    date: 'el-date-picker',
    datetime: 'el-date-picker',
    time: 'el-time-picker',
    rate: 'el-rate',
    slider: 'el-slider',
    upload: 'el-upload'
  }
  return componentMap[type] || 'el-input'
}

// 表单配置
const handleFormConfig = () => {
  formConfigVisible.value = true
}

// 保存表单配置
const saveFormConfig = () => {
  formConfigVisible.value = false
  ElMessage.success('表单配置已保存')
}

// 预览表单
const handlePreview = () => {
  if (formItems.value.length === 0) {
    ElMessage.warning('请先添加表单组件')
    return
  }
  
  // 初始化预览数据
  const data = {}
  formItems.value.forEach(item => {
    data[item.field] = item.defaultValue
  })
  previewData.value = data
  previewVisible.value = true
}

// 预览提交测试
const handlePreviewSubmit = () => {
  console.log('表单数据:', previewData.value)
  ElMessage.success('提交成功！请查看控制台输出')
}

// 清空表单
const handleClear = () => {
  ElMessageBox.confirm('确定要清空所有组件吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    formItems.value = []
    selectedItem.value = null
    ElMessage.success('已清空')
  })
}

// 保存表单
const handleSave = () => {
  if (!formConfig.name) {
    ElMessage.warning('请先配置表单名称')
    return
  }
  
  if (formItems.value.length === 0) {
    ElMessage.warning('请先添加表单组件')
    return
  }
  
  const formData = {
    config: formConfig,
    items: formItems.value
  }
  
  console.log('保存表单:', formData)
  ElMessage.success('表单保存成功！')
}

// 导出JSON
const handleExport = () => {
  const formData = {
    config: formConfig,
    items: formItems.value
  }
  
  const jsonStr = JSON.stringify(formData, null, 2)
  
  // 创建下载链接
  const blob = new Blob([jsonStr], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `${formConfig.name || '表单配置'}.json`
  a.click()
  URL.revokeObjectURL(url)
  
  ElMessage.success('JSON配置已导出')
}

// 导入JSON
const handleImport = () => {
  importJson.value = ''
  importVisible.value = true
}

// 确认导入
const handleImportConfirm = () => {
  try {
    const data = JSON.parse(importJson.value)
    
    if (data.config) {
      Object.assign(formConfig, data.config)
    }
    
    if (data.items && Array.isArray(data.items)) {
      formItems.value = data.items
      selectedItem.value = null
    }
    
    importVisible.value = false
    ElMessage.success('JSON配置导入成功')
  } catch (error) {
    ElMessage.error('JSON格式错误，请检查后重试')
  }
}
</script>

<style scoped>
.form-designer {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f7fa;
}

.toolbar {
  height: 60px;
  background: white;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
}

.toolbar-left {
  display: flex;
  gap: 10px;
}

.toolbar-right .form-name {
  font-size: 16px;
  font-weight: 500;
  color: #303133;
}

.designer-container {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.component-panel {
  width: 280px;
  background: white;
  border-right: 1px solid #e4e7ed;
  overflow-y: auto;
}

.design-panel {
  flex: 1;
  background: white;
  margin: 0 1px;
  overflow-y: auto;
}

.property-panel {
  width: 320px;
  background: white;
  border-left: 1px solid #e4e7ed;
  overflow-y: auto;
}

.panel-header {
  height: 50px;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
}

.panel-header h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: #303133;
}

.component-list {
  padding: 20px;
}

.component-group {
  margin-bottom: 20px;
}

.group-title {
  font-size: 12px;
  color: #909399;
  margin-bottom: 10px;
  font-weight: 500;
}

.group-items {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.component-item {
  padding: 12px;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  cursor: grab;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transition: all 0.3s;
  background: white;
}

.component-item:hover {
  border-color: #409eff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
}

.component-item:active {
  cursor: grabbing;
}

.component-item span {
  font-size: 12px;
  color: #606266;
  text-align: center;
}

.design-area {
  min-height: calc(100vh - 110px);
  padding: 20px;
}

.empty-design {
  height: 300px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
  border: 2px dashed #e4e7ed;
  border-radius: 6px;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.form-items {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.form-item-wrapper {
  position: relative;
  padding: 16px;
  border: 2px solid transparent;
  border-radius: 6px;
  transition: all 0.3s;
}

.form-item-wrapper:hover {
  border-color: #e4e7ed;
  background: #fafafa;
}

.form-item-wrapper.active {
  border-color: #409eff;
  background: #f0f9ff;
}

.form-item-content {
  pointer-events: none;
}

.form-item-actions {
  position: absolute;
  top: -10px;
  right: 10px;
  display: none;
  gap: 4px;
}

.form-item-wrapper:hover .form-item-actions,
.form-item-wrapper.active .form-item-actions {
  display: flex;
}

.property-content {
  padding: 20px;
}

.no-selection {
  text-align: center;
  color: #909399;
  padding: 40px 0;
}

.property-group {
  margin-bottom: 24px;
}

.property-group .group-title {
  font-size: 14px;
  color: #303133;
  margin-bottom: 16px;
  font-weight: 500;
  border-bottom: 1px solid #e4e7ed;
  padding-bottom: 8px;
}

.options-config {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.option-item {
  display: flex;
  gap: 8px;
  align-items: center;
}

.preview-content {
  max-height: 500px;
  overflow-y: auto;
  padding: 20px;
  background: #fafafa;
  border-radius: 6px;
}
</style>